﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.IO.MemoryMappedFiles;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Media.Imaging;

namespace BmpForm1
{
    public partial class Form1 : DevExpress.XtraEditors.XtraForm
    {
        // 缩略图缓存和播放控制
        private List<ImageInfo> _imageCache = new List<ImageInfo>();
        private readonly object _cacheLock = new object();
        private int _currentIndex = 0;
        private System.Windows.Forms.Timer _slideTimer = new System.Windows.Forms.Timer();
        private bool _isPlaying = false;
        private int _interval = 2000;
        private CancellationTokenSource _cancellationTokenSource;
        public Form1()
        {
            InitializeComponent();
            SetupUI();
            SetupTimer();
        }

        private void SetupUI()
        {
            this.Text = "BMP图片读取";
            this.Size = new Size(900, 700);
            this.StartPosition = FormStartPosition.CenterScreen;
            this.DoubleBuffered = true;

            // 控制面板
            var panel = new Panel
            {
                Dock = DockStyle.Top,
                Height = 120,
                BackColor = SystemColors.ControlLight
            };

            // 文件夹选择按钮
            var btnFolder = new Button
            {
                Text = "选择文件夹",
                Location = new Point(20, 20),
                Size = new Size(100, 30)
            };
            btnFolder.Click += BtnFolder_Click;

            // 播放按钮
            btnPlay = new Button
            {
                Text = "播放",
                Location = new Point(140, 20),
                Size = new Size(80, 30),
                Enabled = false
            };
            btnPlay.Click += BtnPlay_Click;

            // 暂停按钮
            btnPause = new Button
            {
                Text = "暂停",
                Location = new Point(240, 20),
                Size = new Size(80, 30),
                Enabled = false
            };
            btnPause.Click += BtnPause_Click;

            // 停止按钮
            btnStop = new Button
            {
                Text = "停止",
                Location = new Point(340, 20),
                Size = new Size(80, 30),
                Enabled = false
            };
            btnStop.Click += BtnStop_Click;

            // 取消加载按钮
            btnCancel = new Button
            {
                Text = "取消加载",
                Location = new Point(440, 20),
                Size = new Size(100, 30),
                Enabled = false
            };
            btnCancel.Click += BtnCancel_Click;

            // 浏览文件
            btnFolder = new Button
            {
                Text = "浏览文件",
                Location = new Point(540, 20),
                Size = new Size(100, 30),
                Enabled = true
            };
            btnFolder.Click += BtnFolder_Click;

            // 速度控制
            var lblSpeed = new Label
            {
                Text = "播放速度(ms):",
                Location = new Point(20, 70),
                AutoSize = true
            };

            numInterval = new NumericUpDown
            {
                Location = new Point(120, 65),
                Width = 80,
                Minimum = 20,
                Maximum = 10000,
                Value = _interval,
                Increment = 500
            };
            numInterval.ValueChanged += (s, e) =>
            {
                _interval = (int)numInterval.Value;
                _slideTimer.Interval = _interval;
            };

            // 缩略图质量设置
            var lblQuality = new Label
            {
                Text = "缩略图质量:",
                Location = new Point(220, 70),
                AutoSize = true
            };

            cmbQuality = new ComboBox
            {
                Location = new Point(300, 65),
                Width = 120,
                DropDownStyle = ComboBoxStyle.DropDownList
            };
            cmbQuality.Items.AddRange(new object[] { "高 (慢)", "中 (推荐)", "低 (最快)" });
            cmbQuality.SelectedIndex = 2;

            // 缓存模式
            var lblCacheMode = new Label
            {
                Text = "缓存模式:",
                Location = new Point(440, 70),
                AutoSize = true
            };

            cmbCacheMode = new ComboBox
            {
                Location = new Point(520, 65),
                Width = 120,
                DropDownStyle = ComboBoxStyle.DropDownList
            };
            cmbCacheMode.Items.AddRange(new object[] { "内存缓存", "磁盘缓存" });
            cmbCacheMode.SelectedIndex = 0;

            // 文件计数和进度
            lblStatus = new Label
            {
                Location = new Point(20, 95),
                Size = new Size(600, 20),
                Text = "状态: 等待选择文件夹"
            };

            // 进度条
            progressBar = new ProgressBar
            {
                Location = new Point(20, 115),
                Size = new Size(600, 20),
                Style = ProgressBarStyle.Continuous
            };

            // 添加控件到面板
            panel.Controls.Add(btnFolder);
            panel.Controls.Add(btnPlay);
            panel.Controls.Add(btnPause);
            panel.Controls.Add(btnStop);
            panel.Controls.Add(btnCancel);
            panel.Controls.Add(lblSpeed);
            panel.Controls.Add(numInterval);
            panel.Controls.Add(lblQuality);
            panel.Controls.Add(cmbQuality);
            panel.Controls.Add(lblCacheMode);
            panel.Controls.Add(cmbCacheMode);
            panel.Controls.Add(lblStatus);
            panel.Controls.Add(progressBar);

            // 图片显示区域
            pictureBox = new PictureBox
            {
                Dock = DockStyle.Fill,
                BackColor = Color.Black,
                SizeMode = PictureBoxSizeMode.Zoom,
                BorderStyle = BorderStyle.FixedSingle,
                WaitOnLoad = false
            };
            pictureBox.DoubleBuffered();

            // 添加到窗体
            this.Controls.Add(panel);
            this.Controls.Add(pictureBox);
        }

        // UI控件声明
        private Button btnPlay, btnPause, btnStop, btnCancel, btnFolder;
        private PictureBox pictureBox;
        private Label lblStatus;
        private ProgressBar progressBar;
        private NumericUpDown numInterval;
        private ComboBox cmbQuality;
        private ComboBox cmbCacheMode;

        private void SetupTimer()
        {
            _slideTimer.Tick += (s, e) => ShowNextThumbnail();
            _slideTimer.Interval = _interval;
        }

        private async void BtnFolder_Click(object sender, EventArgs e)
        {
            using (var fbd = new FolderBrowserDialog())
            {
                fbd.Description = "选择包含BMP文件的文件夹";

                if (fbd.ShowDialog() == DialogResult.OK)
                {
                    try
                    {
                        // 重置状态
                        StopPlayback();
                        ClearImageCache();

                        string folderPath = fbd.SelectedPath;
                        lblStatus.Text = $"正在扫描文件夹: {folderPath}";
                        btnCancel.Enabled = true;
                       // btnFolder.Enabled = false;

                        // 获取所有BMP文件
                        var bmpFiles = GetBmpFiles(folderPath);

                        if (bmpFiles.Length == 0)
                        {
                            lblStatus.Text = "文件夹中没有找到BMP文件";
                            return;
                        }

                        lblStatus.Text = $"正在加载 {bmpFiles.Length} 个BMP文件的缩略图...";
                        progressBar.Maximum = bmpFiles.Length;
                        progressBar.Value = 0;

                        // 创建取消令牌
                        _cancellationTokenSource = new CancellationTokenSource();

                        // 异步加载所有缩略图
                        await LoadAllThumbnailsAsync(bmpFiles, _cancellationTokenSource.Token);

                        lblStatus.Text = $"已加载 {_imageCache.Count} 个缩略图 | 准备播放";
                        btnPlay.Enabled = true;
                        btnStop.Enabled = true;
                        //btnCancel.Enabled = false;
                        //btnFolder.Enabled = true;
                    }
                    catch (OperationCanceledException)
                    {
                        lblStatus.Text = "加载已取消";
                        ClearImageCache();
                    }
                    catch (Exception ex)
                    {
                        lblStatus.Text = $"错误: {ex.Message}";
                        MessageBox.Show($"加载失败:\n{ex.Message}", "错误",
                            MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                    finally
                    {
                        //btnCancel.Enabled = false;
                        //b/tnFolder.Enabled = true;
                    }
                }
            }
        }

        private string[] GetBmpFiles(string folderPath)
        {
            try
            {
                return Directory.GetFiles(folderPath, "*.bmp", SearchOption.TopDirectoryOnly)
                    .Concat(Directory.GetFiles(folderPath, "*.BMP", SearchOption.TopDirectoryOnly))
                    .Distinct()
                    .OrderBy(f => f)
                    .ToArray();
            }
            catch (Exception ex)
            {
                MessageBox.Show($"扫描文件时出错:\n{ex.Message}", "错误",
                    MessageBoxButtons.OK, MessageBoxIcon.Error);
                return Array.Empty<string>();
            }
        }

        private async Task LoadAllThumbnailsAsync(string[] filePaths, CancellationToken token)
        {
            _imageCache.Clear();
            int processed = 0;

            // 根据质量设置选择策略
            var qualityMode = cmbQuality.SelectedIndex;
            var cacheMode = cmbCacheMode.SelectedIndex;

            // 使用ParallelOptions控制并发
            var options = new ParallelOptions
            {
                MaxDegreeOfParallelism = Environment.ProcessorCount,
                CancellationToken = token
            };

            try
            {
                await Task.Run(() =>
                {
                    Parallel.ForEach(filePaths, options, (file, state) =>
                    {
                        options.CancellationToken.ThrowIfCancellationRequested();

                        try
                        {
                            Bitmap thumbnail = null;

                            // 根据质量模式选择加载方法
                            switch (qualityMode)
                            {
                                case 0: // 高质量
                                    thumbnail = LoadHighQualityThumbnail(file, 800);
                                    break;
                                case 1: // 平衡
                                    thumbnail = LoadBalancedThumbnail(file, 800);
                                    break;
                                case 2: // 快速
                                    thumbnail = LoadFastThumbnail(file, 800);
                                    break;
                            }

                            if (thumbnail != null)
                            {
                                var imageInfo = new ImageInfo
                                {
                                    Thumbnail = thumbnail,
                                    FilePath = file,
                                    FileName = Path.GetFileName(file)
                                };

                                _imageCache.Add(imageInfo);
                            }
                        }
                        catch (Exception ex)
                        {
                            DebugLog($"错误处理文件 {Path.GetFileName(file)}: {ex.Message}");
                        }
                        finally
                        {
                            Interlocked.Increment(ref processed);
                            this.BeginInvoke((Action)(() => progressBar.Value = processed));
                        }
                    });
                });
            }
            finally
            {
                // 确保UI更新
                this.BeginInvoke((Action)(() =>
                {
                    lblStatus.Text = $"加载完成: {_imageCache.Count}/{filePaths.Length} 个文件";
                }));
            }
        }

        private Bitmap LoadHighQualityThumbnail(string filePath, int maxWidth)
        {
            // 高质量模式使用WPF解码器
            using (var fileStream = File.OpenRead(filePath))
            {
                var bitmapImage = new BitmapImage();

                bitmapImage.BeginInit();
                bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
                bitmapImage.DecodePixelWidth = maxWidth;
                bitmapImage.StreamSource = fileStream;
                bitmapImage.EndInit();
                bitmapImage.Freeze();

                return ConvertToWinFormsBitmap(bitmapImage);
            }
        }

        private Bitmap LoadBalancedThumbnail(string filePath, int maxWidth)
        {
            // 平衡模式使用原生.NET方法
            using (var src = System.Drawing.Image.FromStream(
                new MemoryStream(File.ReadAllBytes(filePath)),
                false,
                false))
            {
                double ratio = (double)maxWidth / src.Width;
                int newHeight = (int)(src.Height * ratio);

                var thumb = new Bitmap(maxWidth, newHeight);
                using (var g = Graphics.FromImage(thumb))
                {
                    g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighSpeed;
                    g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Low;
                    g.DrawImage(src, 0, 0, maxWidth, newHeight);
                }
                return thumb;
            }
        }

        private Bitmap LoadFastThumbnail(string filePath, int maxWidth)
        {
            try
            {
                // 获取文件信息
                var fileInfo = new FileInfo(filePath);
                long fileSize = fileInfo.Length;

                // 根据文件大小选择处理方式
                if (fileSize > 100 * 1024 * 1024) // 大于100MB的文件
                {
                    return LoadGiantBmpWithMemoryMap(filePath, maxWidth);
                }
                else
                {
                    return LoadBmpWithSampling(filePath, maxWidth);
                }
            }
            catch (Exception ex)
            {
                DebugLog($"加载缩略图失败: {ex.Message}");
                return CreatePlaceholderThumbnail(maxWidth, maxWidth);
            }
        }

        private Bitmap LoadGiantBmpWithMemoryMap(string filePath, int maxWidth)
        {
            using (var mmf = MemoryMappedFile.CreateFromFile(
                filePath, FileMode.Open, null, 0, MemoryMappedFileAccess.Read))
            {
                using (var accessor = mmf.CreateViewAccessor(0, 0, MemoryMappedFileAccess.Read))
                {
                    // 读取文件头
                    byte[] header = new byte[54];
                    accessor.ReadArray(0, header, 0, 54);

                    // 解析基本信息
                    int width = BitConverter.ToInt32(header, 18);
                    int height = Math.Abs(BitConverter.ToInt32(header, 22));
                    int bitsPerPixel = BitConverter.ToInt16(header, 28);
                    int dataOffset = BitConverter.ToInt32(header, 10);

                    // 计算缩略图尺寸
                    double ratio = (double)maxWidth / width;
                    int thumbWidth = maxWidth;
                    int thumbHeight = (int)(height * ratio);

                    // 如果原图小于缩略图尺寸，使用平衡模式
                    if (width <= thumbWidth && height <= thumbHeight)
                    {
                        return LoadBalancedThumbnail(filePath, maxWidth);
                    }

                    // 创建缩略图
                    var thumb = new Bitmap(thumbWidth, thumbHeight, PixelFormat.Format24bppRgb);

                    // 使用内存映射访问器创建缩略图
                    CreateSampledThumbnailFromMemoryMap(accessor, dataOffset, width, height,
                                                      bitsPerPixel, thumb, thumbWidth, thumbHeight);

                    return thumb;
                }
            }
        }

        private unsafe void CreateSampledThumbnailFromMemoryMap(
    MemoryMappedViewAccessor accessor, long dataOffset,
    int origWidth, int origHeight, int bitsPerPixel,
    Bitmap thumb, int thumbWidth, int thumbHeight)
        {
            // 计算行大小（考虑4字节对齐）
            int bytesPerPixel = bitsPerPixel / 8;
            int origRowSize = (int)Math.Ceiling((origWidth * bytesPerPixel) / 4.0) * 4;

            // 计算抽样密度
            int sampleDensity = CalculateSampleDensity(origWidth, origHeight);

            // 使用LockBits高效处理缩略图
            var bmpData = thumb.LockBits(
                new Rectangle(0, 0, thumbWidth, thumbHeight),
                ImageLockMode.WriteOnly,
                PixelFormat.Format24bppRgb);

            try
            {
                byte* thumbScan0 = (byte*)bmpData.Scan0;
                int thumbStride = bmpData.Stride;

                // 计算缩放比例
                double xRatio = (double)origWidth / thumbWidth;
                double yRatio = (double)origHeight / thumbHeight;

                // 并行处理缩略图的每一行
                Parallel.For(0, thumbHeight, y =>
                {
                    // 计算原始图像中的对应行
                    int origY = (int)(y * yRatio);
                    if (origY >= origHeight) origY = origHeight - 1;

                    // 获取缩略图行指针
                    byte* thumbRow = thumbScan0 + y * thumbStride;

                    // 处理缩略图的每一列
                    for (int x = 0; x < thumbWidth; x += sampleDensity)
                    {
                        // 计算原始图像中的对应列
                        int origX = (int)(x * xRatio);
                        if (origX >= origWidth) origX = origWidth - 1;

                        // 计算原始像素位置
                        long pixelPos = dataOffset + (origHeight - 1 - origY) * (long)origRowSize + origX * (long)bytesPerPixel;

                        // 读取像素颜色
                        Color color = ReadPixelColor(accessor, pixelPos, bytesPerPixel);

                        // 填充当前像素和周围像素
                        for (int dx = 0; dx < sampleDensity; dx++)
                        {
                            int px = x + dx;
                            if (px >= thumbWidth) break;

                            int pixelOffset = px * 3;
                            thumbRow[pixelOffset] = color.B;     // Blue
                            thumbRow[pixelOffset + 1] = color.G; // Green
                            thumbRow[pixelOffset + 2] = color.R; // Red
                        }
                    }
                });
            }
            finally
            {
                thumb.UnlockBits(bmpData);
            }
        }

        private unsafe Bitmap LoadBmpWithSampling(string filePath, int maxWidth)
        {
            using (var fs = File.OpenRead(filePath))
            {
                // 读取文件头
                byte[] header = new byte[54];
                if (fs.Read(header, 0, 54) != 54)
                    return CreatePlaceholderThumbnail(maxWidth, maxWidth);

                // 解析基本信息
                int width = BitConverter.ToInt32(header, 18);
                int height = Math.Abs(BitConverter.ToInt32(header, 22));
                int bitsPerPixel = BitConverter.ToInt16(header, 28);
                int dataOffset = BitConverter.ToInt32(header, 10);

                // 计算缩略图尺寸
                double ratio = (double)maxWidth / width;
                int thumbWidth = maxWidth;
                int thumbHeight = (int)(height * ratio);

                // 如果原图小于缩略图尺寸，使用平衡模式
                if (width <= thumbWidth && height <= thumbHeight)
                {
                    return LoadBalancedThumbnail(filePath, maxWidth);
                }

                // 创建缩略图
                var thumb = new Bitmap(thumbWidth, thumbHeight, PixelFormat.Format24bppRgb);

                // 计算抽样密度
                int sampleDensity = CalculateSampleDensity(width, height);

                // 计算行大小（考虑4字节对齐）
                int bytesPerPixel = bitsPerPixel / 8;
                int rowSize = (int)Math.Ceiling((width * bytesPerPixel) / 4.0) * 4;

                // 使用LockBits高效处理缩略图
                var bmpData = thumb.LockBits(
                    new Rectangle(0, 0, thumbWidth, thumbHeight),
                    ImageLockMode.WriteOnly,
                    PixelFormat.Format24bppRgb);

                try
                {
                    byte* thumbScan0 = (byte*)bmpData.Scan0;
                    int thumbStride = bmpData.Stride;

                    // 计算缩放比例
                    double xRatio = (double)width / thumbWidth;
                    double yRatio = (double)height / thumbHeight;

                    // 并行处理缩略图的每一行
                    Parallel.For(0, thumbHeight, y =>
                    {
                        // 计算原始图像中的对应行
                        int origY = (int)(y * yRatio);
                        if (origY >= height) origY = height - 1;

                        // 获取缩略图行指针
                        byte* thumbRow = thumbScan0 + y * thumbStride;

                        // 处理缩略图的每一列
                        for (int x = 0; x < thumbWidth; x += sampleDensity)
                        {
                            // 计算原始图像中的对应列
                            int origX = (int)(x * xRatio);
                            if (origX >= width) origX = width - 1;

                            // 计算文件位置
                            long pixelPos = dataOffset + (height - 1 - origY) * (long)rowSize + origX * (long)bytesPerPixel;

                            // 移动到像素位置
                            fs.Seek(pixelPos, SeekOrigin.Begin);

                            // 读取像素数据
                            byte[] pixelData = new byte[bytesPerPixel];
                            if (fs.Read(pixelData, 0, bytesPerPixel) != bytesPerPixel)
                                continue;

                            // 转换为颜色
                            Color color = bytesPerPixel switch
                            {
                                4 => Color.FromArgb(pixelData[3], pixelData[2], pixelData[1], pixelData[0]),
                                3 => Color.FromArgb(pixelData[2], pixelData[1], pixelData[0]),
                                2 => Decode16BitColor(pixelData),
                                1 => Color.FromArgb(pixelData[0], pixelData[0], pixelData[0]),
                                _ => Color.Magenta
                            };

                            // 填充当前像素和周围像素
                            for (int dx = 0; dx < sampleDensity; dx++)
                            {
                                int px = x + dx;
                                if (px >= thumbWidth) break;

                                int pixelOffset = px * 3;
                                thumbRow[pixelOffset] = color.B;     // Blue
                                thumbRow[pixelOffset + 1] = color.G; // Green
                                thumbRow[pixelOffset + 2] = color.R; // Red
                            }
                        }
                    });
                }
                finally
                {
                    thumb.UnlockBits(bmpData);
                }

                return thumb;
            }
        }

        private int CalculateSampleDensity(int width, int height)
        {
            // 基于图像尺寸动态计算抽样密度
            double megapixels = (width * height) / 1000000.0;

            // 根据百万像素数返回抽样密度
            return megapixels switch
            {
                > 200 => 4,   // 超大型图像 - 低抽样密度
                > 100 => 6,
                > 50 => 8,
                > 20 => 12,  // 大型图像
                > 10 => 16,  // 中型图像
                > 5 => 24,  // 小型图像
                _ => 32   // 超小型图像 - 高抽样密度
            };
        }

        private Color ReadPixelColor(MemoryMappedViewAccessor accessor, long position, int bytesPerPixel)
        {
            try
            {
                switch (bytesPerPixel)
                {
                    case 4: // 32bpp ARGB
                        byte b = accessor.ReadByte(position);
                        byte g = accessor.ReadByte(position + 1);
                        byte r = accessor.ReadByte(position + 2);
                        byte a = accessor.ReadByte(position + 3);
                        return Color.FromArgb(a, r, g, b);

                    case 3: // 24bpp RGB
                        b = accessor.ReadByte(position);
                        g = accessor.ReadByte(position + 1);
                        r = accessor.ReadByte(position + 2);
                        return Color.FromArgb(r, g, b);

                    case 2: // 16bpp
                        ushort pixel = accessor.ReadUInt16(position);
                        return Decode16BitColor(pixel);

                    case 1: // 8bpp
                        byte gray = accessor.ReadByte(position);
                        return Color.FromArgb(gray, gray, gray);

                    default:
                        return Color.Magenta;
                }
            }
            catch
            {
                return Color.Magenta;
            }
        }

        private Color Decode16BitColor(byte[] data)
        {
            // 处理16位RGB (5-6-5)
            ushort pixel = BitConverter.ToUInt16(data, 0);
            return Decode16BitColor(pixel);
        }

        private Color Decode16BitColor(ushort pixel)
        {
            int r = (pixel >> 11) & 0x1F;
            int g = (pixel >> 5) & 0x3F;
            int b = pixel & 0x1F;

            // 扩展到8位
            return Color.FromArgb(
                (r << 3) | (r >> 2),
                (g << 2) | (g >> 4),
                (b << 3) | (b >> 2));
        }

        private Bitmap CreatePlaceholderThumbnail(int width, int height)
        {
            var thumb = new Bitmap(width, height);
            using (var g = Graphics.FromImage(thumb))
            {
                g.Clear(Color.DarkGray);
                using (var font = new Font("Arial", 12))
                {
                    string text = $"{width}×{height}";
                    SizeF textSize = g.MeasureString(text, font);
                    g.DrawString(text, font, Brushes.White,
                        (width - textSize.Width) / 2,
                        (height - textSize.Height) / 2);
                }
            }
            return thumb;
        }

        private void DebugLog(string message)
        {
            // 实际应用中可记录到文件
            System.Diagnostics.Debug.WriteLine($"[{DateTime.Now:HH:mm:ss.fff}] {message}");
        }


        private Bitmap ConvertToWinFormsBitmap(BitmapSource src)
        {
            // 优化转换过程
            var bitmap = new Bitmap(
                src.PixelWidth,
                src.PixelHeight,
                PixelFormat.Format32bppPArgb);

            var data = bitmap.LockBits(
                new Rectangle(0, 0, bitmap.Width, bitmap.Height),
                ImageLockMode.WriteOnly,
                bitmap.PixelFormat);

            src.CopyPixels(
                System.Windows.Int32Rect.Empty,
                data.Scan0,
                data.Height * data.Stride,
                data.Stride);

            bitmap.UnlockBits(data);
            return bitmap;
        }

        private void ShowNextThumbnail()
        {
            if (!_imageCache.Any()) return;

            // 更新索引并循环
            _currentIndex = (_currentIndex + 1) % _imageCache.Count;
            DisplayCurrentThumbnail();
        }

        private void DisplayCurrentThumbnail()
        {
            if (_currentIndex < _imageCache.Count)
            {
                var imageInfo = _imageCache.ElementAt(_currentIndex);
                pictureBox.Image = imageInfo.Thumbnail;
                lblStatus.Text = $"播放中: {_currentIndex + 1}/{_imageCache.Count} - {imageInfo.FileName}";
            }
        }

        private void BtnPlay_Click(object sender, EventArgs e)
        {
            if (!_imageCache.Any()) return;

            if (!_isPlaying)
            {
                _isPlaying = true;
                _slideTimer.Start();
                btnPlay.Enabled = false;
                btnPause.Enabled = true;

                // 如果是第一次播放，显示第一张
                if (pictureBox.Image == null)
                {
                    _currentIndex = 0;
                    DisplayCurrentThumbnail();
                }
            }
        }

        private void BtnPause_Click(object sender, EventArgs e)
        {
            if (_isPlaying)
            {
                _isPlaying = false;
                _slideTimer.Stop();
                btnPlay.Enabled = true;
                btnPause.Enabled = false;
            }
        }

        private void BtnStop_Click(object sender, EventArgs e)
        {
            StopPlayback();
            _currentIndex = 0;
            pictureBox.Image = null;
            lblStatus.Text = $"已停止 | 已加载 {_imageCache.Count} 个缩略图";
        }

        private void BtnCancel_Click(object sender, EventArgs e)
        {
            if (_cancellationTokenSource != null && !_cancellationTokenSource.IsCancellationRequested)
            {
                _cancellationTokenSource.Cancel();
                //btnCancel.Enabled = false;
            }
        }

        private void StopPlayback()
        {
            _isPlaying = false;
            _slideTimer.Stop();
            btnPlay.Enabled = _imageCache.Any();
            btnPause.Enabled = false;
        }

        private void ClearImageCache()
        {
            foreach (var imgInfo in _imageCache)
            {
                imgInfo.Thumbnail?.Dispose();
            }
            _imageCache.Clear();
            _currentIndex = 0;

            // 强制垃圾回收
            GC.Collect();
            GC.WaitForPendingFinalizers();
        }

        protected override void OnFormClosing(FormClosingEventArgs e)
        {
            base.OnFormClosing(e);
            _cancellationTokenSource?.Cancel();
            ClearImageCache();
            _slideTimer.Stop();
            _slideTimer.Dispose();
        }

    }

    public class ImageInfo
    {
        public Bitmap Thumbnail { get; set; }
        public string FilePath { get; set; }
        public string FileName { get; set; }
    }

    public static class ControlExtensions
    {
        // 扩展方法启用双缓冲
        public static void DoubleBuffered(this Control control, bool enable = true)
        {
            var doubleBufferPropertyInfo = control.GetType().GetProperty(
                "DoubleBuffered",
                System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);

            doubleBufferPropertyInfo?.SetValue(control, enable, null);
        }
    }
}
